package comp353Games;
/**
 * SnortController defines a "referee" for the game Snort.  It keeps track of 
 *  the current player's turn, prompts them for their move and determines when 
 *  the game has finished.
 * 
 * @author Andre Harvey, Deanna Fink, Tyler Radley
 * @version February 13, 2012
 */

//imported packages
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class SnortController implements MouseListener {

    //instance variables
    
    /**
     * Current Player.
     */
    private int currentPlayer;
    
    /**
     * Current Player.
     */
    private JLabel errorLabel;
    
    /**
     * The underlying game.
     */
    private Snort game;
    
    /**
     * The Frame containing the display of the Snort game
     */
    private JFrame frame;
    
    /**
     * A Label showing the current player's turn
     */
    private JLabel statusBar;
    
    /**
     * The display of the game
     */
    private SnortDisplay snortGUI;    
   
    
    //constants
    
    /**
     * Number of players
     */
    public static final int NUM_PLAYERS = 2;
    
    
    //public methods
    
    /**
     * Class constructor for generic game.
     * 
     * @param game  Snort game to begin with.
     */
     public void SnortController(){
       
        //Create and set up the window.
        this.frame = new JFrame("Snort");
        this.frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.frame.setPreferredSize((new SnortDisplay(this.game)).getPreferredSize());
        
        frame.setJMenuBar(this.createMenuBar() );
        this.statusBar = new JLabel("Welcome to Snort.  It's Player 1's turn.", SwingConstants.CENTER);
        this.statusBar.setPreferredSize((new SnortDisplay(this.game)).getStatusBarPreferredSize());
        this.frame.add(statusBar,BorderLayout.NORTH);
        
        this.errorLabel = new JLabel("", SwingConstants.CENTER);
        this.errorLabel.setPreferredSize((new SnortDisplay(this.game)).getStatusBarPreferredSize());
        this.frame.add(errorLabel,BorderLayout.SOUTH);
        
        this.frame.addMouseListener(this);
        this.displayGame();   
        
        //Display the window.
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }
    
    /**
     * Public Constructor for the game.
     */
    public SnortController(Snort game) {
        this.game = game;
        this.currentPlayer = 1;
        if (game.hasMovesRemaining(this.currentPlayer)){
            System.out.println("It's Player "+ currentPlayer+"'s turn...");
        }
        this.snortGUI = new SnortDisplay(this.game);
        snortGUI.setVisible(true);
        
    }
    
    /**
     * Sets up the menu that displays at the top of the game window
     * @return a JMenuBar for the game
     */
    public JMenuBar createMenuBar() {
        JMenuBar menuBar;
        JMenu menu;
        JMenuItem newGame,exit;
        //Create the menu bar.
        menuBar = new JMenuBar();

        //Build the first menu.
        menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_A);
        menu.getAccessibleContext().setAccessibleDescription(
                "The only menu in this program that has menu items");
        menuBar.add(menu);

        //a group of JMenuItems
        newGame = new JMenuItem("New Game",
                                 KeyEvent.VK_T);
        //menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead
        newGame.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_N, ActionEvent.ALT_MASK));
        newGame.getAccessibleContext().setAccessibleDescription(
                "Starts a new Game");
        
        newGame.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent event) {
                 newGameActionPerformed(event);
            }
        });
        
        exit = new JMenuItem("Exit",
                                 KeyEvent.VK_T);
        //menuItem.setMnemonic(KeyEvent.VK_T); //used constructor instead
        exit.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_E, ActionEvent.ALT_MASK));
        exit.getAccessibleContext().setAccessibleDescription(
                "Exits the game and returns to Openning Window");
        
        exit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent event) {
                 exitActionPerformed(event);
            }
        });
        
        
        menu.add(newGame);
        menu.add(exit);
        menuBar.add(menu);
        return menuBar;
    }
    
    /**
     * Dictates the action taken when a user selects "New Game" from the File menu
     * @param event The mouse event that triggered this method
     */
    private void newGameActionPerformed(java.awt.event.ActionEvent event) { 
        Object[] options = {"Yes",
            "No, return to the game"};
        int n = JOptionPane.showOptionDialog(frame,
            "If you start a new game, player "+this.currentPlayer+" loses. Continue anyway?",
            "",
            JOptionPane.YES_NO_CANCEL_OPTION,
            JOptionPane.WARNING_MESSAGE,
            null,
            options,
            options[1]);
        if (n==0){
            this.frame.dispose();
            new Thread(new Runnable() {
                public void run() {
                    SnortController.main(null);
                }
            }).start();
        }
    }                

    /**
     * Dictates the action taken when a user selects "Exit" from the File menu
     * @param event The mouse event that triggered this method
     */
    private void exitActionPerformed(java.awt.event.ActionEvent event) {
        Object[] options = {"Yes",
            "No, return to the game"};
        int n = JOptionPane.showOptionDialog(frame,
            "If you exit the game, player "+this.currentPlayer+" loses. Continue anyway?",
            "",
            JOptionPane.YES_NO_CANCEL_OPTION,
            JOptionPane.WARNING_MESSAGE,
            null,
            options,
            options[1]);
        if (n==0){
            this.frame.dispose();
            new Thread(new Runnable() {
                public void run() {
                    Opener.main(null);
                }
            }).start();
        }
        
    }    
    
    /**
     * Creates a display for the game.
     */
    public void displayGame() {
        this.frame.setContentPane(new SnortDisplay(this.game));
        this.frame.getContentPane().add(statusBar,BorderLayout.NORTH);
        this.frame.getContentPane().add(errorLabel,BorderLayout.SOUTH);
        this.frame.setBackground(Color.pink);
        this.frame.pack();
        this.frame.repaint();
    }
        
  
    /**
     * Moves to a new game
     *
     * @param game  New game to make a move to.
     */
    public void move(Snort game) {
        this.game = game;
        this.currentPlayer++;
        if (this.currentPlayer > NUM_PLAYERS) {
            currentPlayer = 1;
        }
        
        if (game.hasMovesRemaining(this.currentPlayer)){
            statusBar.setText("It's Player "+ currentPlayer+"'s turn...");
        }
        this.displayGame();
        if ((!game.hasMovesRemaining(this.currentPlayer))){
            statusBar.setText("Sorry, player " + this.currentPlayer + ", there are no more moves for you, you lose. Close the game window to end this program.");
        }
    }
    
    /**
     * Plays the game, alternating turns between the two players.
     * 
     * @param   rowIndex    the index of the row being played in
     * @param   colIndex       the index of the column being played in 
     */
    public void playGame(int rowIndex, int colIndex) {
        //Create and set up the window.
        if(game.validMove(colIndex,rowIndex, currentPlayer,true)){
            setError("");
            this.move(game.move(rowIndex, colIndex, this.currentPlayer));
        }
        else{
            setError(game.getErrorMessage());
        }
        
        this.frame.repaint();
        
    }
    
    
    /**
     * Sets the text for the error message
     * 
     * @param status    The error message that errorLabel is being set to
     */
    public void setError(String status){
        errorLabel.setText(status);
    }
    
    /**
     * Returns a string version of this.
     *
     * @param indent  Indentation string.
     * @return      An empty string.
     */
    public String toString(String indent){
        String string = "";
        return string;
    }
  
    
    @Override
    public String toString() {
        return this.toString("");
    }
  
    @Override
    public void mouseClicked (java.awt.event.MouseEvent event) {
        int[] xBounds = new int[100];
        int[] yBounds = new int[100];
        int colIndex;
        int rowIndex;
        int xPosition = event.getX();
        int yPosition = event.getY();
        // Check if the click was inside the rectangle area.
        for (int i = 0; i < game.getRows().length; i++) {
            for (int j = 0; j < game.getRows()[i].length; j++){
                xBounds[j] =j*30+45;
                yBounds[i] = i *35 +100;
                if ((xPosition > xBounds[j] && xPosition < xBounds[j]+30) && yPosition >yBounds[i] && 
                        yPosition < yBounds[i]+30){
                            rowIndex = (int)(Math.floor((event.getY()-101)/35));
                            colIndex = (int)(Math.floor((event.getX()-46)/30));

                            playGame(rowIndex, colIndex);
                }
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
    
    
    
  
    /**
     * Main method for testing.
     */
    public static void main(String[] args) { 
        Snort game0 = new Snort();
        SnortController controller = new SnortController(game0);
        controller.SnortController();
    }
   
} 
